package com.uduemc.biso.node.web.api.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.uduemc.biso.core.utils.JsonResult;
import com.uduemc.biso.node.core.common.dto.information.InformationTitleItem;
import com.uduemc.biso.node.core.entities.SInformation;
import com.uduemc.biso.node.core.entities.SInformationTitle;
import com.uduemc.biso.node.core.entities.SSystem;
import com.uduemc.biso.node.core.entities.custom.InformationOne;
import com.uduemc.biso.node.web.api.dto.information.RequestInformationClean;
import com.uduemc.biso.node.web.api.dto.information.RequestInformationDeletes;
import com.uduemc.biso.node.web.api.dto.information.RequestInformationList;
import com.uduemc.biso.node.web.api.dto.information.RequestInformationReductions;
import com.uduemc.biso.node.web.api.dto.information.RequestInformationSave;
import com.uduemc.biso.node.web.api.dto.information.RequestInformationTitleResetOrder;
import com.uduemc.biso.node.web.api.dto.information.RequestInformationTitleSave;
import com.uduemc.biso.node.web.api.service.InformationService;
import com.uduemc.biso.node.web.api.service.SystemService;
import com.uduemc.biso.node.web.api.service.hostsetup.HSSystemDataNumService;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

@RestController
@RequestMapping("/api/system/information")
@Api(tags = "信息系统管理模块")
public class InformationController {

	private final Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private SystemService systemServiceImpl;

	@Autowired
	private InformationService informationServiceImpl;

	@Autowired
	private HSSystemDataNumService hSSystemDataNumServiceImpl;

	@ApiImplicitParams({ @ApiImplicitParam(name = "systemId", value = "信息系统的系统ID", required = true) })
	@ApiOperation(value = "列表信息系统Title（属性）数据", notes = "获取参数 systemId 下的所有信息系统的Title（属性）数据")
	@ApiResponses({ @ApiResponse(code = 200, message = "返回 data 信息，同 /title-info 单个信息系统Title（属性）数据 ") })
	@PostMapping("/title-infos")
	public JsonResult titleInfos(@RequestParam("systemId") long systemId) throws IOException {
		if (systemId < 1) {
			return JsonResult.illegal();
		}

		SSystem system = systemServiceImpl.getCurrentInfoById(systemId);
		if (system == null) {
			return JsonResult.illegal();
		}

		List<SInformationTitle> listSInformationTitle = informationServiceImpl.findSInformationTitleByHostSiteSystemId(systemId);
		return JsonResult.ok(listSInformationTitle);
	}

	@ApiImplicitParams({ @ApiImplicitParam(name = "titleId", value = "信息系统的Title（属性）数据ID", required = true) })
	@ApiOperation(value = "单个信息系统Title（属性）数据", notes = "获取参数 titleId 信息系统的Title（属性）数据")
	@ApiResponses({
			@ApiResponse(code = 200, message = "返回 data 信息，\n type：字段类型，1-用户自定义 2-图片项 3-文件项\n title：信息名称\n siteSearch：是否可查询 0-否 1-是 默认0\n siteRequired：是否为必填项 0-否 1-是 默认0\n proportion：比例因子 默认-1\n placeholder: 站点端搜索input框中的placeholder\n status：状态 0-不显示 1-显示，默认1\n conf：JSON 字符串，type 为 2、3 时的配置项，因为新增至针对 type 为 1 的用户自定义项，所有，该字段只针对修改时起作用。") })
	@PostMapping("/title-info")
	public JsonResult titleInfo(@RequestParam("titleId") long titleId) throws IOException {
		if (titleId < 1) {
			return JsonResult.illegal();
		}

		SInformationTitle sInformationTitle = informationServiceImpl.findSInformationTitle(titleId);
		if (sInformationTitle == null) {
			return JsonResult.illegal();
		}

		return JsonResult.ok(sInformationTitle);
	}

	@PostMapping("/title-info-save")
	@ApiOperation(value = "保存信息系统Title（属性）", notes = "对信息系统Title（属性）数据进行保存，如果传入的id>0修改数据，否则新增数据")
	public JsonResult titleInfoSave(@Valid @RequestBody RequestInformationTitleSave informationTitleSave, BindingResult errors) throws IOException {
		if (errors.hasErrors()) {
			for (FieldError fieldError : errors.getFieldErrors()) {
				String defaultMessage = fieldError.getDefaultMessage();
				String field = fieldError.getField();
				logger.info("field: " + field + " defaultMessage: " + defaultMessage);
				return JsonResult.messageError(defaultMessage);
			}
		}

		long titleId = informationTitleSave.getTitleId();
		long systemId = informationTitleSave.getSystemId();
		SInformationTitle data = null;
		if (titleId > 0) {
			// 修改
			SInformationTitle sInformationTitle = informationServiceImpl.findSInformationTitle(titleId, systemId);
			if (sInformationTitle == null) {
				return JsonResult.illegal();
			}
			SInformationTitle makeSInformationTitle = informationTitleSave.makeSInformationTitle(sInformationTitle);
			data = informationServiceImpl.updateSInformationTitle(makeSInformationTitle);
			if (data == null) {
				return JsonResult.assistance();
			}
		} else {
			// 新增
			long afterId = informationTitleSave.getAfterId();
			if (afterId > 0) {
				SInformationTitle sInformationTitle = informationServiceImpl.findSInformationTitle(afterId, systemId);
				if (sInformationTitle == null) {
					return JsonResult.illegal();
				}
			}

			// 获取总数
			int total = informationServiceImpl.totalSInformationTitleByHostSiteSystemId(systemId);
			if (total >= 20) {
				return JsonResult.messageError("信息系统属性数据总数不能超过20个！");
			}

			data = informationServiceImpl.insertSInformationTitle(informationTitleSave);
			if (data == null) {
				return JsonResult.assistance();
			}
		}

		return JsonResult.messageSuccess("保存成功！", data);
	}

	@ApiImplicitParams({ @ApiImplicitParam(name = "titleId", value = "信息系统的Title（属性）数据ID", required = true),
			@ApiImplicitParam(name = "status", value = "信息系统的Title（属性）状态 0-不显示 1-显示", required = true) })
	@ApiOperation(value = "修改单个信息系统Title（属性）状态", notes = "通过参数 titleId 获取信息系统Title（属性）数据，然后修改其状态。")
	@PostMapping("/title-update-status")
	public JsonResult titleUpdateStatus(@RequestParam("titleId") long titleId, @RequestParam("status") short status) throws IOException {
		if (titleId < 1) {
			return JsonResult.illegal();
		}
		if (status < 0 || status > 1) {
			return JsonResult.illegal();
		}

		SInformationTitle sInformationTitle = informationServiceImpl.findSInformationTitle(titleId);
		if (sInformationTitle == null) {
			return JsonResult.illegal();
		}

		sInformationTitle.setStatus(status);
		SInformationTitle update = informationServiceImpl.updateSInformationTitle(sInformationTitle);

		if (update == null) {
			return JsonResult.assistance();
		}

		return JsonResult.messageSuccess("修改属性状态成功！", update);
	}

	@ApiOperation(value = "统一信息系统Title（属性）排序", notes = "参数 titleIds 是 systemId 该信息系统Title（属性）的全部数据ID。")
	@PostMapping("/title-reset-order")
	public JsonResult titleResetOrder(@Valid @RequestBody RequestInformationTitleResetOrder informationTitleResetOrder, BindingResult errors)
			throws IOException {

		long systemId = informationTitleResetOrder.getSystemId();
		List<Long> titleIds = informationTitleResetOrder.getTitleIds();
		if (CollUtil.isEmpty(titleIds)) {
			return JsonResult.illegal();
		}
		// 获取总数
		int total = informationServiceImpl.totalSInformationTitleByHostSiteSystemId(systemId);
		if (total != titleIds.size()) {
			return JsonResult.messageError("该信息系统Title（属性）的总数与参数titleIds总数不匹配。");
		}

		boolean bool = informationServiceImpl.resetSInformationTitleOrdernum(titleIds, systemId);
		if (!bool) {
			return JsonResult.assistance();
		}
		return JsonResult.ok(1);
	}

	@ApiImplicitParams({ @ApiImplicitParam(name = "titleId", value = "信息系统的Title（属性）数据ID", required = true) })
	@ApiOperation(value = "删除信息系统Title（属性）数据", notes = "获取参数 titleId 信息系统的Title（属性）数据，然后进行删除")
	@PostMapping("/title-delete")
	public JsonResult titleDelete(@RequestParam("titleId") long titleId) throws IOException {
		if (titleId < 1) {
			return JsonResult.illegal();
		}

		SInformationTitle sInformationTitle = informationServiceImpl.findSInformationTitle(titleId);
		if (sInformationTitle == null) {
			return JsonResult.illegal();
		}

		SInformationTitle delete = informationServiceImpl.deleteSInformationTitle(titleId);
		if (delete == null) {
			return JsonResult.assistance();
		}

		return JsonResult.messageSuccess("删除属性成功！", delete);
	}

	@ApiOperation(value = "信息系统列表数据")
	@PostMapping("/data-infos")
	public JsonResult dataInfos(@Valid @RequestBody RequestInformationList informationList, BindingResult errors) throws IOException {
		if (errors.hasErrors()) {
			for (FieldError fieldError : errors.getFieldErrors()) {
				String defaultMessage = fieldError.getDefaultMessage();
				String field = fieldError.getField();
				logger.info("field: " + field + " defaultMessage: " + defaultMessage);
				return JsonResult.messageError(defaultMessage);
			}
		}
		return JsonResult.ok(informationServiceImpl.informationList(informationList));
	}

	@ApiOperation(value = "信息系统回收站列表数据")
	@PostMapping("/data-refuse-infos")
	public JsonResult dataRefuseInfos(@Valid @RequestBody RequestInformationList informationList, BindingResult errors) throws IOException {
		if (errors.hasErrors()) {
			for (FieldError fieldError : errors.getFieldErrors()) {
				String defaultMessage = fieldError.getDefaultMessage();
				String field = fieldError.getField();
				logger.info("field: " + field + " defaultMessage: " + defaultMessage);
				return JsonResult.messageError(defaultMessage);
			}
		}
		return JsonResult.ok(informationServiceImpl.refuseInformationList(informationList));
	}

	@ApiOperation(value = "单个 information 数据信息")
	@ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "信息系统数据ID", required = true) })
	@PostMapping("/data-info")
	public JsonResult dataInfo(@RequestParam("id") long id) throws IOException {
		InformationOne informationOne = informationServiceImpl.informationOne(id);
		if (informationOne == null) {
			return JsonResult.illegal();
		}
		return JsonResult.ok(informationOne);
	}

	@ApiOperation(value = "保存信息数据", notes = "对信息系统数据进行保存，如果传入的id>0修改数据，否则新增数据")
	@PostMapping("/data-save")
	public JsonResult dataSave(@Valid @RequestBody RequestInformationSave informationSave, BindingResult errors) throws IOException {
		if (errors.hasErrors()) {
			for (FieldError fieldError : errors.getFieldErrors()) {
				String defaultMessage = fieldError.getDefaultMessage();
				String field = fieldError.getField();
				logger.info("field: " + field + " defaultMessage: " + defaultMessage);
				return JsonResult.messageError(defaultMessage);
			}
		}
		long id = informationSave.getId();
		long systemId = informationSave.getSystemId();
		SSystem system = systemServiceImpl.getCurrentInfoById(systemId);
		if (system == null || system.getSystemTypeId().longValue() != 7) {
			return JsonResult.illegal();
		}

		List<InformationTitleItem> titleItem = informationSave.getTitleItem();
		if (CollUtil.isEmpty(titleItem)) {
			return JsonResult.illegal();
		}

		List<SInformationTitle> listSInformationTitle = informationServiceImpl.findSInformationTitleByHostSiteSystemId(systemId);
		for (InformationTitleItem informationTitleItem : titleItem) {
			Optional<SInformationTitle> findFirst = listSInformationTitle.stream().filter(item -> {
				return informationTitleItem.getInformationTitleId() == item.getId().longValue();
			}).findFirst();
			if (!findFirst.isPresent()) {
				// 存在不匹配的 titleId
				return JsonResult.illegal();
			}
		}

		boolean bool = false;
		for (InformationTitleItem informationTitleItem : titleItem) {
			if (StrUtil.isNotBlank(informationTitleItem.getValue())) {
				bool = true;
			}
		}
		if (bool == false) {
			// 传入过来的item数据全部为空
			return JsonResult.illegal();
		}

		InformationOne data = null;
		if (id > 0) {
			// 校验
			SInformation sInformation = informationServiceImpl.findSInformation(id, systemId);
			if (sInformation == null) {
				return JsonResult.illegal();
			}
			// 修改
			data = informationServiceImpl.updateInformation(informationSave, sInformation);
		} else {
			// 新增的情况下判断数据是否超过2000条
			int num = hSSystemDataNumServiceImpl.informationitemNum();
			int usedNum = hSSystemDataNumServiceImpl.usedInformationitemNum();
			if (usedNum >= num) {
				return JsonResult.messageError("已使用" + usedNum + "条信息数据项，无法添加，请联系管理员！");
			}
			// 新增
			data = informationServiceImpl.insertInformation(informationSave);
		}

		if (data == null) {
			return JsonResult.assistance();
		}

		// 验证
		return JsonResult.ok(data);
	}

	@ApiOperation(value = "删除单个信息数据", notes = "返回被删除的数据列表")
	@PostMapping("/data-delete")
	public JsonResult dataDelete(@RequestParam("id") long id) throws IOException {
		if (id < 1) {
			return JsonResult.illegal();
		}
		SInformation sInformation = informationServiceImpl.findSInformation(id);
		if (sInformation == null) {
			return JsonResult.illegal();
		}

		Long systemId = sInformation.getSystemId();
		List<Long> ids = new ArrayList<>();
		ids.add(id);

		List<InformationOne> deleteInformation = informationServiceImpl.deleteInformation(systemId, ids);
		if (CollUtil.isEmpty(deleteInformation) || deleteInformation.size() != ids.size()) {
			return JsonResult.assistance();
		}

		return JsonResult.ok(deleteInformation);
	}

	@ApiOperation(value = "批量删除信息数据", notes = "返回被删除的数据列表")
	@PostMapping("/data-deletes")
	public JsonResult dataDeletes(@Valid @RequestBody RequestInformationDeletes informationDeletes, BindingResult errors) throws IOException {

		long systemId = informationDeletes.getSystemId();
		List<Long> ids = informationDeletes.getIds();
		if (CollUtil.isEmpty(ids)) {
			return JsonResult.illegal();
		}

		// 验证 ids 是否都是 sysmteId 的数据
		List<SInformation> list = informationServiceImpl.findSInformationByIds(systemId, ids);
		if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
			return JsonResult.illegal();
		}

		List<InformationOne> deleteInformation = informationServiceImpl.deleteInformation(systemId, ids);
		if (CollUtil.isEmpty(deleteInformation) || deleteInformation.size() != ids.size()) {
			return JsonResult.assistance();
		}

		return JsonResult.ok(deleteInformation);
	}

	@ApiOperation(value = "还原单个信息数据", notes = "返回被还原的数据列表")
	@PostMapping("/data-reduction")
	public JsonResult dataReduction(@RequestParam("id") long id) throws IOException {
		if (id < 1) {
			return JsonResult.illegal();
		}
		SInformation sInformation = informationServiceImpl.findSInformation(id);
		if (sInformation == null) {
			return JsonResult.illegal();
		}

		Long systemId = sInformation.getSystemId();
		List<Long> ids = new ArrayList<>();
		ids.add(id);

		List<InformationOne> list = informationServiceImpl.reductionInformation(systemId, ids);
		if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
			return JsonResult.assistance();
		}

		return JsonResult.ok(list);
	}

	@ApiOperation(value = "批量还原信息数据", notes = "返回被还原的数据列表")
	@PostMapping("/data-reductions")
	public JsonResult dataReductions(@Valid @RequestBody RequestInformationReductions informationReductions, BindingResult errors) throws IOException {

		long systemId = informationReductions.getSystemId();
		List<Long> ids = informationReductions.getIds();
		if (CollUtil.isEmpty(ids)) {
			return JsonResult.illegal();
		}

		// 验证 ids 是否都是 sysmteId 的数据
		List<SInformation> list = informationServiceImpl.findSInformationByIds(systemId, ids);
		if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
			return JsonResult.illegal();
		}

		List<InformationOne> listInformationOne = informationServiceImpl.reductionInformation(systemId, ids);
		if (CollUtil.isEmpty(listInformationOne) || listInformationOne.size() != ids.size()) {
			return JsonResult.assistance();
		}

		return JsonResult.ok(listInformationOne);
	}

	@ApiOperation(value = "回收站单个清除信息数据", notes = "返回被清除的数据列表")
	@PostMapping("/data-clean")
	public JsonResult dataClean(@RequestParam("id") long id) throws IOException {
		if (id < 1) {
			return JsonResult.illegal();
		}
		SInformation sInformation = informationServiceImpl.findSInformation(id);
		if (sInformation == null) {
			return JsonResult.illegal();
		}

		Long systemId = sInformation.getSystemId();
		List<Long> ids = new ArrayList<>();
		ids.add(id);

		List<InformationOne> list = informationServiceImpl.cleanInformation(systemId, ids);
		if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
			return JsonResult.assistance();
		}

		return JsonResult.ok(list);
	}

	@ApiOperation(value = "回收站批量清除信息数据", notes = "返回被清除的数据列表")
	@PostMapping("/data-cleans")
	public JsonResult dataCleans(@Valid @RequestBody RequestInformationClean informationClean, BindingResult errors) throws IOException {

		long systemId = informationClean.getSystemId();
		List<Long> ids = informationClean.getIds();
		if (CollUtil.isEmpty(ids)) {
			return JsonResult.illegal();
		}

		// 验证 ids 是否都是 sysmteId 的数据
		List<SInformation> list = informationServiceImpl.findSInformationByIds(systemId, ids);
		if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
			return JsonResult.illegal();
		}

		List<InformationOne> listInformationOne = informationServiceImpl.cleanInformation(systemId, ids);
		if (CollUtil.isEmpty(listInformationOne) || listInformationOne.size() != ids.size()) {
			return JsonResult.assistance();
		}

		return JsonResult.ok(listInformationOne);
	}

	@ApiOperation(value = "回收站清空", notes = "返回传入的参数 信息系统的系统ID 执行完成")
	@ApiImplicitParams({ @ApiImplicitParam(name = "systemId", value = "信息系统的系统ID", required = true) })
	@PostMapping("/data-clean-all")
	public JsonResult dataCleanAll(@RequestParam("systemId") long systemId) throws IOException {
		if (systemId < 1) {
			return JsonResult.illegal();
		}
		SSystem system = systemServiceImpl.getCurrentInfoById(systemId);
		if (system == null || system.getSystemTypeId().longValue() != 7) {
			return JsonResult.illegal();
		}

		informationServiceImpl.cleanAllInformation(systemId);

		return JsonResult.ok(systemId);
	}

	@ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "信息系统的数据ID", required = true),
			@ApiImplicitParam(name = "status", value = "信息系统的状态 0-不显示 1-显示", required = true) })
	@ApiOperation(value = "修改单个信息系统数据状态", notes = "通过参数 id 获取信息系统数据，然后修改其状态。")
	@PostMapping("/data-update-status")
	public JsonResult dataUpdateStatus(@RequestParam("id") long id, @RequestParam("status") short status) throws IOException {
		if (id < 1) {
			return JsonResult.illegal();
		}
		SInformation sInformation = informationServiceImpl.findSInformation(id);
		if (sInformation == null) {
			return JsonResult.illegal();
		}
		sInformation.setStatus(status);
		SInformation update = informationServiceImpl.updateSInformation(sInformation);
		if (update == null) {
			return JsonResult.assistance();
		}
		return JsonResult.messageSuccess("修改状态成功！", informationServiceImpl.informationOne(id));
	}

	@ApiOperation(value = "通过系统ID获取到导入模板的下载链接地址")
	@ApiImplicitParams({ @ApiImplicitParam(name = "systemId", value = "信息系统的系统ID", required = true) })
	@PostMapping("/excel-demo")
	public JsonResult excelDemo(@RequestParam("systemId") long systemId) throws Exception {
		if (systemId < 1) {
			return JsonResult.illegal();
		}
		SSystem system = systemServiceImpl.getCurrentInfoById(systemId);
		if (system == null || system.getSystemTypeId().longValue() != 7) {
			return JsonResult.illegal();
		}
		String downloadUrl = informationServiceImpl.excelDemoDownloadUrl(systemId);
		if (StrUtil.isBlank(downloadUrl)) {
			return JsonResult.assistance();
		}
		return JsonResult.ok(downloadUrl);
	}

	@ApiOperation(value = "通过资源库中的资源ID，以及系统ID 导入信息系统数据")
	@ApiImplicitParams({ @ApiImplicitParam(name = "repertoryId", value = "资源库中的资源ID", required = true),
			@ApiImplicitParam(name = "systemId", value = "信息系统的系统ID", required = true) })
	@ApiResponses({ @ApiResponse(code = 200, message = "返回 data 信息，插入数据的总数量。") })
	@PostMapping("/excel-import")
	public JsonResult excelImport(@RequestParam("repertoryId") long repertoryId, @RequestParam("systemId") long systemId) throws Exception {
		if (repertoryId < 1 || systemId < 1) {
			return JsonResult.illegal();
		}
		SSystem system = systemServiceImpl.getCurrentInfoById(systemId);
		if (system == null || system.getSystemTypeId().longValue() != 7) {
			return JsonResult.illegal();
		}
		return informationServiceImpl.excelImport(repertoryId, systemId);
	}
}
